package com.eonmind.ai.converts;

import com.eonmind.ai.dto.AiChatDto;
import com.eonmind.common.contract.enums.ai.ConversationMessageTypeEnum;
import com.eonmind.common.contract.enums.ai.ConversationTypeEnum;
import com.eonmind.common.contract.enums.ai.ModelTypeEnum;
import com.eonmind.common.provider.entity.ai.*;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.ai.chat.messages.*;
import org.springframework.ai.model.Media;
import org.springframework.beans.BeanUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;

@Slf4j
public class AiChatConvert {
    public static List<AiChatDto.AiConversationData> toAiConversationDataList(List<AiConversation> contentData) {
        if (contentData == null) {
            return Lists.newArrayList();
        }
        return contentData.stream().map(AiChatConvert::toAiConversationData).toList();
    }

    public static AiChatDto.AiConversationData toAiConversationData(AiConversation aiConversation) {
        AiChatDto.AiConversationData aiConversationData = new AiChatDto.AiConversationData();
        BeanUtils.copyProperties(aiConversation, aiConversationData);
        aiConversationData.setTypeName(Objects.requireNonNull(ConversationTypeEnum.getByCode(aiConversation.getType())).getDesc());

        return aiConversationData;
    }


    public static List<AiChatDto.AiModelData> toAiModelDataList(List<AiModel> aiModelList) {
        return aiModelList.stream().map(AiChatConvert::toAiModelData).toList();
    }

    private static AiChatDto.AiModelData toAiModelData(AiModel aiModel) {
        AiChatDto.AiModelData aiModelData = new AiChatDto.AiModelData();
        BeanUtils.copyProperties(aiModel, aiModelData);
        try {
            aiModelData.setModelTypeName(Objects.requireNonNull(ModelTypeEnum.getByCode(aiModel.getModelType())).getDesc());
        } catch (Exception e) {
            log.error("ModelTypeEnum is not found: {}", aiModel.getModelType());
        }
        return aiModelData;
    }

    public static List<AiChatDto.AiConversationMessageData> toAiConversationMessageDataList(List<AiConversationMessage> messageList) {
        return messageList.stream().map(AiChatConvert::toAiConversationMessageData).toList();
    }

    private static AiChatDto.AiConversationMessageData toAiConversationMessageData(AiConversationMessage aiConversationMessage) {
        AiChatDto.AiConversationMessageData aiConversationMessageData = new AiChatDto.AiConversationMessageData();
        BeanUtils.copyProperties(aiConversationMessage, aiConversationMessageData, "messageMediaList");
        aiConversationMessageData.setMessageMediaList(toMessageMediaDataList(aiConversationMessage.getMessageMediaList()));
        return aiConversationMessageData;
    }

    private static List<AiChatDto.AiConversationMessageData.MessageMediaData> toMessageMediaDataList(List<AiConversationMessage.MessageMedia> messageMediaList) {
        if (ObjectUtils.isEmpty(messageMediaList)) {
            return Lists.newArrayList();
        }
        return messageMediaList.stream().map(messageMedia -> {
            AiChatDto.AiConversationMessageData.MessageMediaData messageMediaData = new AiChatDto.AiConversationMessageData.MessageMediaData();
            BeanUtils.copyProperties(messageMedia, messageMediaData);
            return messageMediaData;
        }).toList();
    }

    public static AiConversationMessage toAiConversationMessage(AiConversation conversation, Message t) {
        AiConversationMessage aiConversationMessage = new AiConversationMessage();
        aiConversationMessage.setConversationId(conversation.getId());
        aiConversationMessage.setUserId(conversation.getUserId());
        aiConversationMessage.setMessageContent(t.getText());
        MessageType messageType = t.getMessageType();
        ConversationMessageTypeEnum typeEnum = ConversationMessageTypeEnum.getByDesc(messageType.getValue());
        if (typeEnum != null) {
            aiConversationMessage.setType(typeEnum.getCode());
        }
        if (t instanceof UserMessage userMessage) {
            aiConversationMessage.setMessageMediaList(toMediaList(userMessage.getMedia()));
        }
        return aiConversationMessage;
    }

    private static List<AiConversationMessage.MessageMedia> toMediaList(List<Media> medias) {
        return medias.stream().map(media -> {
            AiConversationMessage.MessageMedia messageMedia = new AiConversationMessage.MessageMedia();
            messageMedia.setId(media.getId());
            messageMedia.setMimeType(media.getMimeType().getType());
            messageMedia.setData(media.getData());
            messageMedia.setName(media.getName());
            return messageMedia;
        }).toList();
    }


    public static Message toMessageByType(AiConversationMessage aiConversationMessage) {
        Integer type = aiConversationMessage.getType();
        ConversationMessageTypeEnum typeEnum = ConversationMessageTypeEnum.getByCode(type);
        if (typeEnum == null) {
            return new UserMessage("");
        }
        switch (MessageType.fromValue(typeEnum.getDesc())) {
            case USER -> {
                return new UserMessage(aiConversationMessage.getMessageContent());
            }
            case ASSISTANT -> {
                return new AssistantMessage(aiConversationMessage.getMessageContent());
            }
            case SYSTEM -> {
                return new SystemMessage(aiConversationMessage.getMessageContent());
            }
            default -> {
                return null;
            }
        }
    }

    public static AiChatDto.AiChatData toAiChatData(AssistantMessage assistantMessage) {
        AiChatDto.AiChatData aiChatData = new AiChatDto.AiChatData();
        aiChatData.setContent(Optional.ofNullable(assistantMessage.getText()).orElse(""));
        aiChatData.setId(UUID.randomUUID().toString());

        return aiChatData;
    }

    public static List<AiChatDto.AiAssistantData> toAiAssistantDataList(List<AiAssistant> assistantList) {
        return assistantList.stream().map(AiChatConvert::toAiAssistantData).toList();
    }

    private static AiChatDto.AiAssistantData toAiAssistantData(AiAssistant aiAssistant) {
        AiChatDto.AiAssistantData aiAssistantData = new AiChatDto.AiAssistantData();
        BeanUtils.copyProperties(aiAssistant, aiAssistantData);
        return aiAssistantData;
    }

    public static List<AiChatDto.AiModelCategoryData> toAiModelCategoryDataList(List<AiModelCategory> aiModelCategoryList) {
        return aiModelCategoryList.stream().map(AiChatConvert::toAiModelCategoryData).toList();
    }

    private static AiChatDto.AiModelCategoryData toAiModelCategoryData(AiModelCategory aiModelCategory) {
        AiChatDto.AiModelCategoryData aiModelCategoryData = new AiChatDto.AiModelCategoryData();
        BeanUtils.copyProperties(aiModelCategory, aiModelCategoryData);
        return aiModelCategoryData;
    }
}
